//Might move this to the server's shared file

require( "GLON" )
require( "datastream" )
include( "shared.lua" )

//Delay for removing the player's props after they leave. IN SECONDS
RemovePropsDelay = 120

//Spam Protection Delay
SpawnDelay = 1

//Idle Kick time
IdleKickTime = 300

//Use this table for server interactions with the Limits (Like checking them when a player spawns something)
ReadLimits = {}
LTable = {}

//Table of friends for people in the server
FriendsTable = {}
CLFriends = {}

if SERVER then	//Later on, let's change the GLON encoding to normal serialising, so we can actually see the stuff in the .txt file. Ease of use, in this case, is > than efficiemcy.
	//Let's grab our current limits from a .txt GLON encoded table.
	
	function RebuildLimits()	//Move this to a command called by the server when it finishes creating the Ranks Table from the DB
		local WriteTable = {}
		local Ranks = RankTable
		
		if !file.Exists( "xqmLimits/PlayerLimits.txt" ) then
			file.CreateDir( "xqmLimits" )
			
			for rn,r in pairs( Ranks ) do	//Grab the rank and set every limit for it to 1, indexing the table by both the rank, then the limit type.
				WriteTable[r] = {}
				for k,v in pairs( LimitsTable ) do
					WriteTable[r][v] = 1
				end
				print( "RANK: " .. r .. " limits set" )	//Debug each rank.
			end
		
			local ToWrite = glon.encode( WriteTable )
			ReadLimits = WriteTable
			file.Write( "xqmLimits/PlayerLimits.txt", ToWrite )
		else
			ReadLimits = glon.decode( file.Read( "xqmLimits/PlayerLimits.txt" ) )
		end
	end
	hook.Add( "Initialize", "RebuildLimits", RebuildLimits )
	
	function AcceptOwner( pl, handler, id )
		if handler == "SaveLimitsStream" then
			if !string.find( pl:GetNetworkedString( "flags" ), "O" ) then print( "STREAM DENIED" ) return false
			else print( "STREAM ACCEPTED" ) return true end
		else
			return true
		end
	end
	hook.Add( "AcceptStream", "AcceptOwner", AcceptOwner )
 
	function SendLimits( ply, command, args )
		datastream.StreamToClients( { ply }, "LimitsStream", { ReadLimits } )
	end
	concommand.Add( "SendPlayerLimits", SendLimits )
	
	function SaveLimits( ply, handle, id, encoded, decoded )
		ReadLimits = decoded[1]
		PrintTable( ReadLimits )
		//Message players letting them know limits were updated
		for k,v in pairs( player.GetAll() ) do
			v:PrintMessage( HUD_PRINTTALK, "Server limits were updated." )
		end
		file.Write( "xqmLimits/PlayerLimits.txt", glon.encode(ReadLimits) )
	end
	datastream.Hook( "SaveLimitsStream", SaveLimits )
	
	function SendFriends( ply, command, args )
		datastream.StreamToClients( { ply }, "SRVFriendsStream", { FriendsTable[ply:UniqueID()] } )
	end
	concommand.Add( "SendCLFriends", SendFriends )
	
	function ReceiveFriends( ply, handle, id, encoded, decoded )
		for k,v in pairs( FriendsTable[ply:UniqueID()] ) do
			if !table.HasValue( decoded[1], v ) then NotifyFriend( v, ply, "Remove" ) end
		end
		for k,v in pairs( decoded[1] ) do
			if !table.HasValue( FriendsTable[ply:UniqueID()], v ) then NotifyFriend( v, ply, "Add" ) end
		end
		FriendsTable[ply:UniqueID()] = decoded[1]
		PrintTable( FriendsTable )
		print( "SRV Received Friends" )
	end
	datastream.Hook( "CLFriendsStream", ReceiveFriends )
	
	function InitPPTables( ply )
		FriendsTable[ply:UniqueID()] = {}
		PrintTable( FriendsTable )
		ply:SetNetworkedBool( "LimitsSent", false )
	end
	hook.Add( "PlayerInitialSpawn", "InitPPTables", InitPPTables )
	
	function DCPPTables( ply )
		FriendsTable[ply:UniqueID()] = nil
	end
	hook.Add( "PlayerDisconnected", "DCPPTables", DCPPTables )
	
	function CompletedLimitsStream( pl, handler, id, rawdata, procdata )
		if handler == "SaveLimitsStream" then pl:ConCommand( "CloseLimitsPanel" ) end
	end
	hook.Add( "CompletedIncomingStream", "CompletedLimitsStream", CompletedLimitsStream )
	
	function NotifyFriend( target, ply, status )
		if status == "Add"  then
			target:PrintMessage( HUD_PRINTTALK, "You were added to " .. ply:Nick() .. "'s Prop Protection friends list." )
			target:SendLua( "surface.PlaySound( \"UI/buttonrollover.wav\" )" )
		else
			target:PrintMessage( HUD_PRINTTALK, "You were removed from " .. ply:Nick() .. "'s Prop Protection friends list." )
			target:SendLua( "surface.PlaySound( \"UI/buttonrollover.wav\" )" )
		end
	end
	
end

if CLIENT then

function ReceiveLimits( ply, handle, id, encoded, decoded )
	LTable = encoded[1]
	//PANEL:SetTextLimits()
	print( "RECEIVED LIMITS" )
	LocalPlayer():SetNetworkedBool( "LimitsSent", true )
	print( LocalPlayer():GetNetworkedBool( "LimitsSent" ) )
end
datastream.Hook( "LimitsStream", ReceiveLimits )

function ReceiveCLFriends( ply, handle, id, encoded, decoded )
	CLFriends = encoded[1]
	PrintTable( CLFriends )
	print( "CL Received Friends" )
end
datastream.Hook( "SRVFriendsStream", ReceiveCLFriends )

end

//Table of Rank limits
LimitsTable =
{
	"prop_physics",
	"prop_ragdoll",
	"prop_effect",
	"prop_vehicle_airboat",
	"prop_vehicle_prisoner_pod",
	"prop_vehicle_jeep",
	"gmod_anchor",
	"gmod_balloon",
	"gmod_button",
	"gmod_cameraprop",
	"gmod_dynamite",
	"gmod_emitter",
	"gmod_hoverball",
	"gmod_lamp",
	"gmod_light",
	"gmod_rtcameraprop",
	"gmod_spawner",
	"gmod_thruster",
	"gmod_turret",
	"gmod_wheel",
	"gmod_winch_controller",
	"sent_ball",
	"gmod_wire_hoverdrivecontroler",
	"sent_deployableballoons",
	"gmod_adv_dupe_paster",
	"gmod_wire_addressbus",
	"gmod_wire_dataport",
	"gmod_wire_datarate",
	"gmod_wire_gpu",
	"gmod_wire_dynamicmemory",
	"gmod_wire_hdd",
	"gmod_wire_stringbuf",
	"gmod_wire_sensor",
	"gmod_wire_locator",
	"gmod_wire_target_finder",
	"gmod_wire_waypoint",
	"gmod_wire_xyzbeacon",
	"gmod_wire_cpu",
	"gmod_wire_expression",
	"gmod_wire_expression2",
	"gmod_wire_pid",
	"gmod_wire_cd_disk",
	"gmod_wire_cd_ray",
	"gmod_wire_data_satellitedish",
	"gmod_wire_data_store",
	"gmod_wire_data_transferer",
	"gmod_wire_wirer",
	"gmod_wire_damage_detector",
	"gmod_wire_emarker",
	"gmod_wire_gps",
	"gmod_wire_gyroscope",
	"gmod_wire_hsranger",
	"gmod_wire_ranger",
	"gmod_wire_las_reciever",
	"gmod_wire_microphone",
	"gmod_wire_speedometer",
	"gmod_wire_watersensor",
	"gmod_wire_indicator",
	"gmod_wire_adv_hudindicator",
	"gmod_wire_consolescreen",
	"gmod_wire_panel",
	"gmod_wire_digitalscreen",
	"gmod_wire_hudindicator",
	"gmod_wire_lamp",
	"gmod_wire_light",
	"gmod_wire_oscilloscope",
	"gmod_wire_pixel",
	"gmod_wire_screen",
	"gmod_wire_soundemitter",
	"gmod_wire_textscreen",
	"gmod_wire_colorer",
	"gmod_wire_hsholoemitter",
	"gmod_wire_holoemitter",
	"gmod_wire_hologrid",
	"gmod_wire_useholoemitter",
	"gmod_wire_painter",
	"gmod_wire_trail",
	"gmod_wire_fx_emitter",
	"gmod_wire_adv_input",
	"gmod_wire_adv_pod",
	"gmod_wire_button",
	"gmod_wire_string",
	"gmod_wire_value",
	"gmod_wire_dual_input",
	"gmod_wire_eyepod",
	"gmod_wire_graphics_tablet",
	"gmod_wire_notifier",
	"gmod_wire_input",
	"gmod_wire_output",
	"gmod_wire_socket",
	"gmod_wire_plug",
	"gmod_wire_pod",
	"gmod_wire_radio",
	"gmod_wire_relay",
	"gmod_wire_twoway_radio",
	"gmod_wire_keyboard",
	"gmod_wire_numpad",
	"gmod_wire_rtcam",
	"wired_door",
	"gmod_wire_dupeport",
	"gmod_wire_cameracontroller",
	"damage_scaler",
	"gmod_wire_detonator",
	"gmod_wire_explosive",
	"gmod_wire_simple_explosive",
	"gmod_wire_facer",
	"gmod_wire_field_device",
	"gmod_wire_forcer",
	"gmod_wire_grabber",
	"gmod_wire_hoverball",
	"gmod_wire_igniter",
	"gmod_wire_motor",
	"gmod_wire_hydraulic",
	"gmod_wire_nailer",
	"gmod_wire_no_collide",
	"gmod_wire_spawner",
	"gmod_wire_simple_servo",
	"gmod_wire_thruster",
	"gmod_wire_turret",
	"gmod_wire_user",
	"gmod_wire_vectorthruster",
	"gmod_wire_weight",
	"gmod_wire_latch",
	"gmod_wire_wheel",
	"gmod_wire_winch_controller",
	"npc_controller",
	"gmod_xqm_wire_hydraulic",
	"gmod_wire_gate",
	"gmod_wire_wireless_srv",
	"gmod_wire_wireless_recv",
	"gmod_wire_ranger_beta",
	"gmod_wire_target_finder_beta",
	"gmod_wire_rfid_reader_beam",
	"gmod_wire_rfid_implanter",
	"gmod_wire_rfid_reader_prox",
	"gmod_wire_rfid_filter",
	"gmod_wire_rfid_reader_act",
	"gmod_wire_keycardspawner",
	"gmod_wire_keycardreader",
	"gmod_wire_materializer",
	"phys_lengthconstraint",		//SET THESE HIGH, THEY ARE CONSTRAINTS
	"phys_spring",					//
	"phys_hinge",					//
	"phys_constraint",				//
	"keyframe_rope",				//
	"base_gmodentity",				//EXTREMELY HIGH
	"phys_slideconstraint",			//
	"phys_keepupright",				//
	"env_spritetrail",				//
	"madjawa_laser",				//Not High at all
	"gmod_laser",
	"gmod_laser_base",
	"gmod_laser_crystal",
	"gmod_laser_reflector",
	"logic_collision_pair",			//
	"phys_torque",					//
	"phys_pulleyconstraint",			//	Work on adding all of the constraints
	"phys_ballsocket",
	"phys_ragdollconstraint"
}
